#ifndef TERRAIN_H
#define TERRAIN_H

#include "Game Engine\Header\BulletUtil.h"
#include "Game Engine\Header\d3dUtil.h"
#include "Game Engine\Header\Vertex.h"
#include <string>
#include <vector>

struct TerrainVertex
{
	D3DXVECTOR3 pos;
	D3DXVECTOR3 normal;
	D3DXVECTOR2 texC;
};

class Terrain
{
public:
	struct InitInfo
	{
		std::wstring HeightmapFilename;
		std::wstring LayerMapFilename0;
		std::wstring LayerMapFilename1;
		std::wstring LayerMapFilename2;
		std::wstring LayerMapFilename3;
		std::wstring LayerMapFilename4;
		std::wstring BlendMapFilename;
		float HeightScale;
		float HeightOffset;
		UINT NumRows;
		UINT NumCols;
		float CellSpacing;
	};

public:
	Terrain();
	~Terrain();

	float width()const;
	float depth()const;
	float getHeight(float x, float y)const;

	void init(ID3D10Device* device, btDynamicsWorld* world, const InitInfo& initInfo);
	void InitPhysics();

	void setDirectionToSun(const D3DXVECTOR3& v);

	void draw(const D3DXMATRIX& world);

	std::vector<TerrainVertex> GetVertices();
	std::vector<int> GetIndices();

	UINT GetNumVertices();
	int GetNumIndices();

	D3DXMATRIX mWorld;

private:
	void loadHeightmap();
	void smooth();
	bool inBounds(UINT i, UINT j);
	float average(UINT i, UINT j);
	void buildVB();
	void buildIB();
	btRigidBody* LocalCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape);

private:
	btDynamicsWorld* mDynamicsWorld;
	btScalar		mDefaultContactProcessingThreshold;

	InitInfo mInfo;

	UINT mNumVertices;
	UINT mNumFaces;

	std::vector<float> mHeightmap;
 	std::vector<TerrainVertex> mVertices;
	std::vector<int> mIndices;

	ID3D10Device* md3dDevice;
	ID3D10Buffer* mVB;
	ID3D10Buffer* mIB;

	ID3D10ShaderResourceView* mLayer0;
	ID3D10ShaderResourceView* mLayer1;
	ID3D10ShaderResourceView* mLayer2;
	ID3D10ShaderResourceView* mLayer3;
	ID3D10ShaderResourceView* mLayer4;
	ID3D10ShaderResourceView* mBlendMap;

	ID3D10EffectTechnique* mTech;
	ID3D10EffectMatrixVariable* mfxWVPVar;
	ID3D10EffectMatrixVariable* mfxWorldVar;
	ID3D10EffectVectorVariable* mfxDirToSunVar;
	ID3D10EffectShaderResourceVariable* mfxLayer0Var;
	ID3D10EffectShaderResourceVariable* mfxLayer1Var;
	ID3D10EffectShaderResourceVariable* mfxLayer2Var;
	ID3D10EffectShaderResourceVariable* mfxLayer3Var;
	ID3D10EffectShaderResourceVariable* mfxLayer4Var;
	ID3D10EffectShaderResourceVariable* mfxBlendMapVar;

	//keep the collision shapes, for deletion/cleanup
	btAlignedObjectArray<btCollisionShape*>	m_collisionShapes;

	btTriangleIndexVertexArray* m_indexVertexArrays;

	btBroadphaseInterface*	m_broadphase;

	btCollisionDispatcher*	m_dispatcher;

	btConstraintSolver*	m_solver;

	btDefaultCollisionConfiguration* m_collisionConfiguration;

	bool	m_animatedMesh;

	public:

	//to show refit works
	void	setVertexPositions(float waveheight, float offset);
};

#endif // TERRAIN_H